/*
 * Copyright (C), 2002-2018, Caljm有限公司
 * FileName: EchoServer
 * Author:   Byron Wang
 * Date:     2018/10/25 下午10:39
 * Description: //模块目的、功能描述
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */

package com.cpcs.msgpack;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * 功能描述：服务端启动类
 *
 * @author Byron Wang
 * @since 2018/10/25
 */
public class MsgPackServer {

    public static void main(String[] args) {
        try {
            new MsgPackServer().bind(8080, "127.0.0.1");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void bind(int port, String host) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
//                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChildChannelHandler());

            ChannelFuture future = bootstrap.bind(host, port).sync();

            System.out.println("EchoServer started and listen on " + future.channel().localAddress());
            future.channel().closeFuture().sync();

        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {

        @Override
        protected void initChannel(SocketChannel channel) throws Exception {
            channel.pipeline()
                    .addLast("FrameDecoder",new LengthFieldBasedFrameDecoder(65535, 0, 2, 0, 2))
                    .addLast("msgpack decoder", new MsgPackDecoder())
                    .addLast("FrameEecoder", new LengthFieldPrepender(2))
                    .addLast("msgpack encoder", new MsgPackEncoder())
                    .addLast(new MsgPackServerHandler());
        }
    }
}
